package fr.lip6.meta.tools;

import artefact.generic.ConstructionPrimitive;
import artefact.umlClassDiagram.CreateAssociation;
import artefact.umlClassDiagram.CreateAttribute;
import artefact.umlClassDiagram.CreateClass;
import artefact.umlClassDiagram.CreateGeneralization;
import artefact.umlClassDiagram.CreateInterface;
import artefact.umlClassDiagram.CreateOperation;
import artefact.umlClassDiagram.CreateOperationRefinement;
import artefact.umlClassDiagram.CreatePackage;
import artefact.umlClassDiagram.CreateStatement;
import artefact.umlClassDiagram.impl.CreateStatementImpl;

public class StatementPrimitive extends Trigger {


	private ConstructionPrimitive primitive;

	public StatementPrimitive(ConstructionPrimitive ar){

		this.primitive=ar;
	}

	@Override
	public void display() {
		// TODO Auto-generated method stub
		//System.out.println("Creation Statement :"+
		//this.getClass().getName());
	}

	@Override
	public boolean equals(Object o) {
		if (o == this)
			return true;
		else if((o == null) || (o.getClass() != this.getClass()))
			return false;
		else {
			StatementPrimitive st = (StatementPrimitive) o;
			
			if (this.primitive.getClass() != st.primitive.getClass())
				return false;

			// Bizarre present 2 fois ?
			if (st.primitive instanceof CreateClass) {
				CreateClass cc = (CreateClass)st.primitive;
				CreateClass oo = (CreateClass)this.primitive;
				boolean res = ( ("CreateClass("+cc.getName()+")").equals(
						"CreateClass("+oo.getName()+")")&&cc.getOwener().equals(oo.getOwener()));

				//System.out.println("EQUALS Create CLASS :"+("CreateClass("+cc.getName()+")"+ " and "+
				//	"CreateClass("+oo.getName()+")")+"==>"+res );

				return res;
			}

			if (st.primitive instanceof CreateGeneralization) {
				CreateGeneralization ca = (CreateGeneralization)st.primitive;
				CreateGeneralization coo = (CreateGeneralization)this.primitive;
				String p1=ca.getLien().split("::")[1];
				String p2=coo.getLien().split("::")[1];
				return (("CreateGeneralization("+ca.getSub()+","+ca.getSuper()+")").equals(
						"CreateGeneralization("+coo.getSub()+","+coo.getSuper()+")")&&p1.equals(p2));
			}

			if (st.primitive instanceof CreateClass) {
				CreateClass ca = (CreateClass)st.primitive;
				CreateClass coo = (CreateClass)this.primitive;
				return ("CreateClass("+ca.getName()+","+ca.getOwener()+")").equals(
						"CreateClass("+coo.getName()+","+coo.getOwener()+")");
			}

			if (st.primitive instanceof CreatePackage) {
				CreatePackage ca = (CreatePackage)st.primitive;
				CreatePackage coo = (CreatePackage)this.primitive;
				return ("CreatePackage("+ca.getName()+")").equals(
						"CreatePackage("+coo.getName()+")");
			}

			if (st.primitive instanceof CreateAttribute) {
				CreateAttribute ca = (CreateAttribute)st.primitive;
				CreateAttribute coo = (CreateAttribute)this.primitive;
				String p1=ca.getLien().split("::")[1];
				String p2=coo.getLien().split("::")[1];
				return (ca.getName().equals(coo.getName())&&ca.getOwner().equals(coo.getOwner())&&p1.equals(p2));
			}

			if (st.primitive instanceof CreateOperation) {
				CreateOperation crOp = (CreateOperation) st.primitive;
				CreateOperation crOpThis = (CreateOperation) this.primitive;
				

				//Rajouter
				boolean structureSimilaire=true;
				CreateStatementImpl crOpStatement = (CreateStatementImpl) crOp.getBlock();
				CreateStatementImpl crOpStatementThis = (CreateStatementImpl) crOpThis.getBlock();
				while(crOpStatement!=null && crOpStatementThis!=null){
					
					if(!crOpStatement.equals(crOpStatementThis))
						structureSimilaire=false;
					
					crOpStatement=(CreateStatementImpl) crOpStatement.getNext();
					crOpStatementThis=(CreateStatementImpl) crOpStatementThis.getNext();
				}
				//////////
				String[] liens = crOp.getLien().split("::");
				String[] liensThis = crOpThis.getLien().split("::");
				String pckg = liens[1];
				String pckgThis = liensThis[1];
				String parameters = liens.length > 2 ? liens[2] : null;
				String parametersThis = liensThis.length > 2 ? liensThis[2] : null;

				return (
							pckg.equals(pckgThis)
						&&	crOp.getOwener().equals(crOpThis.getOwener())
						&&	crOp.getName().equals(crOpThis.getName())
						&&	(	(parameters != null && parametersThis != null && parameters.equals(parametersThis))
							||	(parameters == null && parametersThis == null)	)
						// Rajouter
						&& structureSimilaire
						//
				);
			}

			if (st.primitive instanceof CreateInterface) {
				CreateInterface ca = (CreateInterface)st.primitive;
				CreateInterface coo = (CreateInterface)this.primitive;

				return (ca.getName().equals(coo.getName())&&ca.getOwner().equals(coo.getOwner()));
			}

			if (st.primitive instanceof CreateOperationRefinement) {
				CreateOperationRefinement ca = (CreateOperationRefinement)st.primitive;
				CreateOperationRefinement coo = (CreateOperationRefinement)this.primitive;
				
				
				//Rajouter
				boolean structureSimilaire=true;
				CreateStatementImpl crOpStatement = (CreateStatementImpl) ca.getBlock();
				CreateStatementImpl crOpStatementThis = (CreateStatementImpl) coo.getBlock();
				while(crOpStatement!=null && crOpStatementThis!=null){
					
					if(!crOpStatement.equals(crOpStatementThis))
						structureSimilaire=false;
					
					crOpStatement=(CreateStatementImpl) crOpStatement.getNext();
					crOpStatementThis=(CreateStatementImpl) crOpStatementThis.getNext();
				}
				//////////
				
				String p1=ca.getLien().split("::")[1];
				String p2=coo.getLien().split("::")[1];
				return (ca.getName().equals(coo.getName())&&ca.getOwner().equals(coo.getOwner())&&p1.equals(p2)&&ca.getSuper().equals(coo.getSuper())						
						&& structureSimilaire
						//
						);
			}
		}
		
		return false;
	}	


	public String toString(){

		if (primitive instanceof CreateClass){
			if(primitive.getLien()==null)
			{
				CreateClass cc = (CreateClass)this.primitive;
				return ("CreateClass("+cc.getName()+","+cc.getOwener()+ ")");
			}
			else
			{

				CreateClass cc = (CreateClass)this.primitive;
				return ("CreateClass("+cc.getName()+","+cc.getOwener()+ ","+cc.getLien()+")");

			}
		}

		if (primitive instanceof CreateInterface){
			if(primitive.getLien()==null)
			{
				CreateInterface cc = (CreateInterface)this.primitive;
				return ("CreateInterface("+cc.getName()+","+cc.getOwner()+ ")");
			}
			else
			{

				CreateInterface cc = (CreateInterface)this.primitive;
				return ("CreateInterface("+cc.getName()+","+cc.getOwner()+ ","+cc.getLien()+")");

			}
		}
		if (primitive instanceof CreateAssociation){
			CreateAssociation ca = (CreateAssociation)this.primitive;
			return ("CreateAssociation("+ca.getSource()+","+ca.getTarget()+")");
		}

		if (primitive instanceof CreatePackage){
			CreatePackage ca = (CreatePackage)primitive;
			if(primitive.getLien()==null)
			{
				return ("CreatePackage("+ca.getName()+ ")");
			}
			else{

				return ("CreatePackage("+ca.getName()+ "," +ca.getLien()+")");
			}
		}

		if (primitive instanceof CreateAttribute){
			CreateAttribute ca = (CreateAttribute)primitive;
			if(primitive.getLien()==null)
			{
				return ("CreateAttribute("+ca.getName()+","+ca.getOwner()+ ")");
			}
			else
			{
				return ("CreateAttribute("+ca.getName()+","+ca.getOwner()+ ","+ca.getLien()+")");	
			}
		}

		if (primitive instanceof CreateOperation){
			CreateOperation ca = (CreateOperation)primitive;
			
			// Rajout
			CreateStatementImpl cs = (CreateStatementImpl) ca.getBlock();
			String s="\n";
			
			while(cs!=null){
				s+="\t"+cs.getStatementName()+"\n";
				cs=(CreateStatementImpl) cs.getNext();
			}
			
			///////////
			if(primitive.getLien()==null)
			{
				
				return ("CreateOperation("+ca.getName()+","+ca.getOwener()+ ")"+s);
			}
			else
			{
				return ("CreateOperation("+ca.getName()+","+ca.getOwener()+ ","+ca.getLien()+")"+s);
			}
		}

		if (primitive instanceof CreateOperationRefinement){
			CreateOperationRefinement ca = (CreateOperationRefinement)primitive;
			// Rajout
			CreateStatementImpl cs = (CreateStatementImpl) ca.getBlock();
			String s="\n";
			while(cs!=null){
				s+="\t"+cs.getStatementName()+"\n";
				cs=(CreateStatementImpl) cs.getNext();
			}
			///////////
			
			
			if(primitive.getLien()==null)
			{
				return ("CreateOperationRefinement("+ca.getName()+","+ca.getOwner()+ ")"+s);
				
			}
			else
			{
				return ("CreateOperationRefinement("+ca.getName()+","+ca.getOwner()+ ","+ ca.getSuper()+","+ca.getLien()+")"+s);	
			}
		}

		if (primitive instanceof CreateGeneralization)
		{
			if(primitive.getLien()==null)
			{
				CreateGeneralization ca = (CreateGeneralization)primitive;
				return ("CreateGeneralization("+ca.getSub()+","+ca.getSuper()+ ")");
			}
			else
			{
				CreateGeneralization ca = (CreateGeneralization)primitive;
				return ("CreateGeneralization("+ca.getSub()+","+ca.getSuper()+","+ca.getLien()+ ")");	
			}
		}



		return primitive.toString();

	}

	public ConstructionPrimitive getPrimitive() {
		return primitive;
	}

	public void setPrimitive(ConstructionPrimitive primitive) {
		this.primitive = primitive;
	}
}
